package com.quanyue.haircut.order.service.impl;

import com.quanyue.auto.util.AssertUtils;
import com.quanyue.auto.util.KeyGenerator;
import com.quanyue.haircut.domain.constant.*;
import com.quanyue.haircut.domain.entity.Card;
import com.quanyue.haircut.domain.entity.CardOrder;
import com.quanyue.haircut.domain.entity.User;
import com.quanyue.haircut.domain.entity.UserIntegral;
import com.quanyue.haircut.order.dto.CardOrderResult;
import com.quanyue.haircut.order.mapper.CardOrderMapper;
import com.quanyue.haircut.order.service.CardOrderService;
import com.quanyue.haircut.order.service.PayService;
import com.quanyue.haircut.shop.mapper.CardMapper;
import com.quanyue.haircut.shop.service.CardService;
import com.quanyue.haircut.shop.service.IntegralService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigInteger;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

@Service
public class CardOrderServiceImpl implements CardOrderService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private CardOrderMapper cardOrderMapper;
    @Autowired
    private IntegralService integralService;
    @Autowired
    private CardMapper cardMapper;
    @Autowired
    private CardService cardService;
    @Autowired
    private PayService payService;

    @Override
    @Transactional
    public CardOrderResult create(Integer merchantNo, User user, CardOrder orderCreate, String ip) {
        CardOrderResult result = new CardOrderResult();
        Map <String, String> map = new HashMap <>();
        if (orderCreate.getCardNo().equals("null")) {
           throw new AssertUtils.ValidateException("请选择会员卡充值或联系管理员添加会员卡");
        }
        orderCreate.setOrderNo(KeyGenerator.createOrderNo(NoPrefix.ORDER.value(), merchantNo, KeyGenerator.uuid()));
        if (orderCreate.getPayChannel().equals(CardPayChannel.WX_ONLINE)) {
            orderCreate.setUserId(user.getId());
            orderCreate.setOrderStatus(OrderStatus.SUBMIT);
            map = payService.pay(OrderType.CARD.name(), user.getMerchantNo(), orderCreate.getPrice(),
                    orderCreate.getOrderNo(), user, ip);
        } else {
            orderCreate.setOrderStatus(OrderStatus.DONE);
        }
        orderCreate.setMerchantNo(merchantNo);
        orderCreate.setCreateTime(LocalDateTime.now());
        orderCreate.setModifyTime(LocalDateTime.now());
        cardOrderMapper.insert(orderCreate);
        result.setCardOrder(orderCreate);
        result.setWxPayUnifiedOrderResult(map);
        return result;
    }

    @Override
    public CardOrder findOrderByNo(String orderNo) {
        return cardOrderMapper.findByOrderNo(orderNo);
    }

    @Override
    @Transactional
    public void afterPayComplete(String orderNo, String payId, PayResult result) {
        CardOrder order = this.findOrderByNo(orderNo);
        if (order.getOrderStatus().equals(OrderStatus.DONE)) return;
        if (result == PayResult.SUCCESS) {
            // 更新订单信息
            order.setPayId(payId);
            order.setOrderStatus(OrderStatus.DONE);
            order.setModifyTime(LocalDateTime.now());
            cardOrderMapper.updateSelective(order);
            // 更新卡片余额
            Card card = cardMapper.findByUserAndShopValid(order.getUserId(), order.getShopId());
            card.setBalance(card.getBalance().add(order.getPrice()));
            card.setModifyTime(LocalDateTime.now());
            cardMapper.updateSelective(card);
            // 更新会员积分
            UserIntegral userIntegral = integralService.findIntegral(order.getUserId(), order.getShopId());
            BigInteger integer = BigInteger.valueOf(order.getPrice().intValue());
            if (userIntegral != null) integer = userIntegral.getIntegral().add(integer);
            integralService.updateIntegral(order.getShopId(), order.getUserId(), integer);
        } else {
            logger.error("weixin pay fail: ", result.name());
        }
    }
}
